<?php

namespace Biz\service\wiki;


use Biz\cache\brand\BrandScanUniKey;
use Biz\model\brand\BrandContentKeywords;
use Biz\model\brand\Content;
use Biz\model\brand\Content as mBrandContent;
use Biz\cache\brand\BrandNameAndAlias;
use Biz\cache\brand\BrandSpu;
use Biz\service\Store\StoreContentSync;
use Doraemon\amqp\Delayed\DelayedContentClaim;
use Doraemon\cache\Queue;
use Doraemon\model\Blank;
use Biz\model\brand\Brand as mBrand;
use Doraemon\model\Photos;
use Doraemon\pockets\IdSender\IdSender;
use Doraemon\service\Content\AdmContent;
use Doraemon\tools\ActionLog;
use Doraemon\tools\BlockType;
use Doraemon\tools\Log;
use Doraemon\tools\Sensors;

/**
 * Class WikiContent
 * @package Biz\service\wiki
 */
class WikiContentSync extends WikiContent
{

    const CLAIM_STEP_ = 1;
    protected static $exec = false;
    protected static $autoClaimData = [];
    protected static $photosAllowStatus = [
        \Doraemon\model\Photos::STATUS_UNTREATED,
        \Doraemon\model\Photos::STATUS_SUCCESS,
        \Doraemon\model\Photos::STATUS_REVIEW
    ];

    /**
     * 设置住友说计数器
     * @param $data
     */
    public static function autoContentCounter($data)
    {
        $brand_id = $data["data"]["brand_id"] ?? 0;
        $change_field = $data["change_field"] ?? [];
        $fieldChange = in_array('claim_content_status', $change_field) || in_array('audit_status', $change_field);
        if ($brand_id > 0 && $fieldChange) {
            try {
                $total = mBrandContent::countClaim($brand_id);

                $uid = \Biz\model\brand\Brand::get('uid', ['id' => $brand_id]);

                if ($uid > 0) \Doraemon\cache\UserCounter::setCounter($uid, [\Doraemon\cache\UserCounter::TYPE_LIVER_SAID => $total]);

                \Doraemon\tools\Log::position_info("autoContentCounter", compact('brand_id', 'total'));

            } catch (\Exception $e) {

                \Doraemon\tools\Log::position_info("autoContentCounter error", compact('brand_id', 'e'));
            }
        }
    }

    public static function autoStickers($data)
    {
        $picItem = $data['data'];
        $type = $data['type'];
        $obj_id = $picItem['note_id'] ?? '';
        if ($obj_id && $type == 'update') {

        }
    }


    /**
     * 监测[store.obj_relate_wiki  内容关联wiki] 触发自动认领
     * @param $data
     */
    public static function autoRelWiki($data)
    {
        $obj_id = $data["data"]["obj_id"] ?? '';
        $type = $data["data"]["type"] ?? '';

        if ($obj_id && !in_array($type, [\Biz\model\wiki\ObjRelateWiki::TYPE_BRAND_REL])) {

            $obj_type = IdSender::getType($obj_id);

            if ($obj_type == 0) {
                $allowStatus = self::$photosAllowStatus;
                $status = \Doraemon\model\Photos::get_master('status', ['id' => $obj_id]);
            } else if ($obj_type == 5) {
                $allowStatus = [\Doraemon\model\Blank::STATUS_WAIT_CHECK, \Doraemon\model\Blank::STATUS_SUCCESS];
                $status = \Doraemon\model\Blank::get_master('status', ['bid' => $obj_id]);
            } else {
                return;
            }

            if (in_array($status, $allowStatus)) return;

            \Doraemon\tools\Log::position_info("autoRelWiki", compact('obj_id'));

            self::auto($type, $obj_id, $status, $allowStatus, __FUNCTION__);
        }

    }

    // 关联关系 修改 同步更新es内容
    public static function syncCommunity()
    {
        $obj_id = $data["data"]["obj_id"] ?? '';
        $type = $data["data"]["type"] ?? '';

        switch ($type) {
            case \Biz\model\wiki\ObjRelateWiki::OBJ_TYPE_NOTE:
                Queue::insertQueue('Photo/afterAudit', ['photo_id' => $obj_id], Queue::QUEUE_ES_SYNC_COMMUNITY);
                break;
            case \Biz\model\wiki\ObjRelateWiki::OBJ_TYPE_BLANK:
            case \Biz\model\wiki\ObjRelateWiki::OBJ_TYPE_ARTICLE:
            case \Biz\model\wiki\ObjRelateWiki::OBJ_TYPE_GUIDE:
                Queue::insertQueue('TotalArticle/updateTotalArticle', ['article_id' => $obj_id], Queue::QUEUE_ES_SYNC_COMMUNITY);
                break;
        }
    }

    /**
     * 监测[hhzhome_content.hhz_blank  空白模板文章] 触发自动认领
     * @param $data
     */
    public static function autoBlank($data)
    {
        //监听maxwell数据处理
        $type = $data['type'] ?? '';
        $obj_id = $data["data"]["bid"] ?? '';
        $status = $data["data"]["status"] ?? -1;
        $change_field = $data["change_field"] ?? [];
        $delStatus = [\Doraemon\model\Blank::STATUS_WAIT_CHECK, \Doraemon\model\Blank::STATUS_SUCCESS];
        $change_switch = true;

        if ($status == \Doraemon\model\Blank::STATUS_FIRST_EDIT) {
            return;
        }

        if ($type == \Doraemon\service\esSearch\Common::TYPE_UPDATE) {
            $change_fields = [
                'remark', 'status', 'title'
            ];
            $change_switch = false;
            foreach ($change_fields as $v) {
                if (in_array($v, $change_field)) {
                    $change_switch = true;
                    break;
                }
            }
            Log::position_info('autoBlank change', $change_field);
        }

        //todo 延迟进行认领操作
        if ($change_switch) self::auto($type, $obj_id, $status, $delStatus, __FUNCTION__);
    }


    /**
     * 监测[hhzhome_content.hhz_article  文章表] 触发自动认领
     * @param $data
     */
    public static function autoArticle($data)
    {
        //监听maxwell数据处理
        $type = $data['type'] ?? '';
        $obj_id = $data["data"]["aid"] ?? '';
        $status = $data["data"]["status"] ?? -1;
        $allowStatus = [\Doraemon\model\Article::STATUS_WAIT_CHECK, \Doraemon\model\Article::STATUS_SUCCESS];

//        self::auto($type, $obj_id, $status, $allowStatus, __FUNCTION__);
    }

    /**
     * 监测[hhzhome_content.hhz_photos_*  note表] 触发自动认领
     * @param $data
     */
    public static function autoPhoto($data)
    {
        //监听maxwell数据处理
        $type = $data['type'] ?? '';
        $obj_id = $data["data"]["id"] ?? '';
        $status = $data["data"]["status"] ?? -1;
        $change_field = $data["change_field"] ?? [];
        $allowStatus = self::$photosAllowStatus;

        $change_switch = true;

        if ($type == \Doraemon\service\esSearch\Common::TYPE_UPDATE) {
            $change_fields = [
                'title','remark', 'status', 'img_tags', 'new_img_tags'
            ];
            $change_switch = false;
            foreach ($change_fields as $v) {
                if (in_array($v, $change_field)) {
                    $change_switch = true;
                    break;
                }
            }
            Log::position_info('autoPhoto change', $change_field);
        }
        if ($change_switch) self::auto($type, $obj_id, $status, $allowStatus, __FUNCTION__);
    }

    public static function delay($type, $obj_id, $status, $allowStatus, $from = '')
    {
        $delete = false;
        //删除状态和操作类型进行更新或删除
        switch ($type) {
            case \Doraemon\service\esSearch\Common::TYPE_ADD:
                break;
            case \Doraemon\service\esSearch\Common::TYPE_UPDATE:
                if (!in_array($status, $allowStatus)) {
                    $delete = true;
                }
                break;
            case \Doraemon\service\esSearch\Common::TYPE_DELETE:
                $delete = true;
                break;
        }
        \Doraemon\tools\Log::position_info("delay autoContent", compact('type', 'obj_id', 'delete', 'status', 'allowStatus', 'from'));

        if ($from == 'autoStickers') return;
        //删除状态和操作类型进行更新或删除
        if ($delete) {
            self::delClaim($obj_id);
        } else {
            self::autoClaim($obj_id);
        }
    }

    public static function auto($type, $obj_id, $status, $allowStatus, $from = '')
    {
        \Doraemon\tools\Log::position_info("$from autoContent", compact('type', 'obj_id', 'status', 'allowStatus'));

        $delayTime = 3;

        $controller = 'queue/async/service/'; // 消费时请求的接口
        $callback = [
            __CLASS__,
            'delay'
        ]; // callback地址
        $params = compact('type', 'obj_id', 'status', 'allowStatus', 'from'); // 参数
        $time = $delayTime . 's';

        $lockKey = BrandScanUniKey::getKey($obj_id);

        if (!BrandScanUniKey::setnx($lockKey, 1)) return true;

        //设置过期时间
        BrandScanUniKey::expire($lockKey, $delayTime);

        DelayedContentClaim::insertQueue($controller, ["callback" => $callback, "params" => $params], DelayedContentClaim::DELAYED_QUEUE_CONTENT_CLAIM, $time);
    }

    public static function getAllIgnore($op_brand_id)
    {
        $response = [];
        //获取品牌忽略的wiki
        $list = empty($op_brand_id) ? \Biz\model\brand\ContentIgnore::getAllIgnore() : \Biz\model\brand\ContentIgnore::getBrandIgnore($op_brand_id);

        if (empty($list)) return $response;

        foreach ($list as $v) {
            $response[$v['brand_id']][] = $v['op_id'];
        }

        return $response;
    }

    public static function getAllBrandKeyWords()
    {
        $where = [
            'brand_type' => array_keys(\Biz\model\brand\Brand::ADM_BRAND_TYPE),
            'status' => \Biz\model\brand\Brand::STATUS_USING
        ];
        $list = \Biz\model\brand\Brand::select(['id', 'brand_name', 'brand_alias', 'uid'], $where);
        //品牌信息
        if (empty($list)) return false;
        $brand_ids = array_column($list, 'id');


        list($brand, $nocache) = BrandNameAndAlias::getData($brand_ids);
        if ($nocache) {
            //检索词
            $search_keywords = BrandContentKeywords::select(['search_keywords', 'brand_id'], ['brand_id' => $brand_ids, 'status' => BrandContentKeywords::STATUS_NORMAL_ON]);
            $search_keywords_list = array_column($search_keywords, 'search_keywords', 'brand_id');
            $saveData = [];
            foreach ($list as $v) {
                $v['search_keywords'] = $search_keywords_list[$v['id']] ?? '';
                $saveData[$v['id']] = $v;
            }

            if ($saveData) {
                BrandNameAndAlias::setData($saveData);
                $brand = $saveData + $brand;
            }
        }

        list($spu, $nocache) = BrandSpu::getData($brand_ids);
        if ($nocache) {
            $where = ['brand_id[>]' => 0, 'basic_state' => \Biz\model\wiki\WikiBasic::ADM_ALLOW_STATE];
            $list = \Biz\model\wiki\WikiBasic::select(['brand_id', 'title', 'series'], $where);
            $list = empty($list) ? [] : $list;
            $temp = [];
            foreach ($list as $v) {
                if ($v['title']) $temp[$v['brand_id']][$v['title']] = $v['title'];
                if ($v['series']) $temp[$v['brand_id']][$v['series']] = $v['series'];
            }
            if ($temp) {
                $temp = array_map('array_values', $temp);
                BrandSpu::setData($temp);
                $spu = $temp + $spu;
            }
        }

        $matchBrandWordsMap = [];
        $brandUidMap = [];
        $brandName = $brand;
        if (empty($brandName)) return compact('matchBrandWordsMap', 'brandUidMap', 'brandName');
        foreach ($brandName as $id => $v) {
            $temp = $spu[$id] ?? [];
            if ($v['brand_name']) $temp[] = $v['brand_name'];
            if ($v['brand_alias']) $temp = array_merge($temp, json_decode($v['brand_alias']));
            if (!empty($v['search_keywords'])) $temp = array_merge($temp, explode(',', $v['search_keywords']));
            $matchBrandWordsMap[$id] = $temp;
            $brandUidMap[$id] = $v['uid'];
        }

        return compact('matchBrandWordsMap', 'brandUidMap', 'brandName');
    }

    public static function getBrandKeyWords($brand_id = [])
    {

        //品牌商旗下商品缓存,添加,删除,修改标题和系列名称重置缓存
        list($spu, $nocache) = BrandSpu::getData($brand_id);

        if ($nocache || (empty($spu) && empty($nocache))) {
            //查询所有品牌商的一级品牌词
            $where = ['brand_id[>]' => 0, 'basic_state' => \Biz\model\wiki\WikiBasic::ADM_ALLOW_STATE];
            if (!empty($brand_id)) $where = ['brand_id' => $brand_id, 'basic_state' => \Biz\model\wiki\WikiBasic::ADM_ALLOW_STATE];
            $list = \Biz\model\wiki\WikiBasic::select([
                'brand_id',
                'title',
                'series'
            ], $where);

            if ($list) {
                $temp = [];
                foreach ($list as $v) {
                    if ($v['title']) $temp[$v['brand_id']][] = $v['title'];
                    if ($v['series']) $temp[$v['brand_id']][] = $v['series'];
                }

                $list = array_map(function ($v) {
                    return array_flip(array_flip($v));
                }, $temp);
//                if (empty($brand_id))
                    BrandSpu::setData($list);
            }
            $spu += (array)$list;
        }

        //品牌商在后台新增或编辑品牌名称、别称重置缓存
        list($brandName, $nocache) = BrandNameAndAlias::getData($brand_id);
        if ($nocache || (empty($brandName) && empty($nocache))) {
            $where = empty($brand_id) ? [
                'brand_type' => array_keys(\Biz\model\brand\Brand::ADM_BRAND_TYPE),
                'status' => \Biz\model\brand\Brand::STATUS_USING
            ]
                : [
                    'brand_type' => array_keys(\Biz\model\brand\Brand::ADM_BRAND_TYPE),
                    'id' => $brand_id, 'status' => \Biz\model\brand\Brand::STATUS_USING
                ];
    
    
            //检索词
            $search_keywords =BrandContentKeywords::select(['search_keywords','brand_id'],
                ['brand_id' => $brand_id, 'status' => BrandContentKeywords::STATUS_NORMAL_ON]);
            $search_keywords_list = array_column($search_keywords,'search_keywords','brand_id');
            
            
            $list = \Biz\model\brand\Brand::select([
                'id',
                'brand_name',
                'brand_alias',
                'uid'
            ], $where);
            if ($list) {
                $list = array_column($list, null, 'id');
                //增加检索词
                foreach ($list as &$item) {
                    if (array_key_exists($item['id'],$search_keywords_list)){
                        $item['search_keywords'] = $search_keywords_list[$item['id']];
                    }
                    
                }
//                if (empty($brand_id))
                    BrandNameAndAlias::setData($list);
            }
            $brandName += (array)$list;
        }

        $matchBrandWordsMap = [];
        $brandUidMap = [];
        if ($brandName) {
            foreach ($brandName as $id => $v) {
                $brandUidMap[$id] = $v['uid'];
                $temp = $spu[$id] ?? [];
                if ($v['brand_name']) $temp[] = $v['brand_name'];
                if ($v['brand_alias']) {
                    $temp = array_merge($temp, json_decode($v['brand_alias']));
                }
                if (isset($v['search_keywords']) && $v['search_keywords']) {
                    $temp = array_merge($temp, explode(',', $v['search_keywords']));
                }
                $matchBrandWordsMap[$id] = $temp;
            }
        }

        return compact('matchBrandWordsMap', 'brandUidMap', 'brandName');
    }

    public static function convert($size)
    {
        $unit = array('b', 'kb', 'mb', 'gb', 'tb', 'pb');
        return @round($size / pow(1024, ($i = floor(log($size, 1024)))), 2) . ' ' . $unit[$i];
    }

    public static function exec()
    {
        self::$exec = true;
    }

    public static function consumeContent($ids = [], $brand_id = 0)
    {
        if ($ids && self::$exec) {
            foreach ($ids as $id) {
                self::autoClaim($id, $brand_id, false);
            }
        }
    }

    public static function scanEsContent($brand_id = [])
    {
        if (is_string($brand_id)) $brand_id = explode(',', $brand_id);
        $brand_id = array_filter($brand_id);
        $brand_id = array_values((array)$brand_id);
        if (empty($brand_id)) {
            $brand_id = \Biz\cache\brand\BrandScanCron::all();
            \Biz\cache\brand\BrandScanCron::clear();
        }
        echo 'brand_id:', implode(',', $brand_id), PHP_EOL;
        if ($brand_id) {
            list('matchBrandWordsMap' => $matchBrandWordsMap,
                'brandUidMap' => $brandUidMap) = \Biz\service\wiki\WikiContentSync::getBrandKeyWords($brand_id);
            foreach ($matchBrandWordsMap as $key => $words) {
                $obj_ids = [];
                echo 'brand_id:', $key, PHP_EOL;
                $brand_uid = $brandUidMap[$key] ?? 0;
                //查询匹配用户发的内容(note)
                $rs = Photos::select('id', ['uid' => $brand_uid]);
                if ($rs) $obj_ids = array_merge($obj_ids, $rs);

                //查询匹配用户发的内容(文章)
                $rs = Blank::select('bid', ['uid' => $brand_uid]);
                if ($rs) $obj_ids = array_merge($obj_ids, $rs);

                self::consumeContent($obj_ids, $key);

                if (!empty($words)) {
                    $rs = \Doraemon\service\search\BrandContent::scrollPhoto($words);
                    echo $key, ':', count($rs), PHP_EOL;
                    if ($rs) $obj_ids = array_merge($obj_ids, $rs);

                    //查询已经存在的内容
                    $exists = mBrandContent::select('obj_id', ['brand_id' => $key, 'claim_content_status[!]' => mBrandContent::CLAIM_CONTENT_IGNORE]);
                    if (!empty($exists)) {
                        $rs = array_merge($rs, $exists);
                        $rs = array_flip(array_flip($rs));
                    }

                    self::consumeContent($rs, $key);
                }
                echo 'total:', count($obj_ids), ' unique:', count(array_flip(array_flip($obj_ids)));
            }
        }

    }

    public static function scanAllContent($brand_id, $op = 0)
    {
        $mem = memory_get_usage();
        $t = microtime(true);

        if ($op & 1) {
            $content = Photos::query("SELECT `id` FROM `hhz_photos_0` WHERE `status` IN (:s1,:s2)", [
                's1' => \Doraemon\model\Photos::STATUS_UNTREATED,
                's2' => \Doraemon\model\Photos::STATUS_SUCCESS]);
            $rs = $content->fetchAll(\PDO::FETCH_COLUMN);
            $t1 = microtime(true) - $t;
            echo "hhz_photos_0 count:" . count($rs) . ", time:$t1", PHP_EOL;
            self::consumeContent($rs, $brand_id);
            $m = self::convert(memory_get_usage() - $mem);
            $t1 = microtime(true) - $t;
            echo "hhz_photos_0 complete memory:$m, time:$t1", PHP_EOL;
        }

        if ($op & 2) {
            $content = Photos::query("SELECT `id` FROM `hhz_photos_1` WHERE `status` IN (:s1,:s2)", [
                's1' => \Doraemon\model\Photos::STATUS_UNTREATED,
                's2' => \Doraemon\model\Photos::STATUS_SUCCESS]);
            $rs = $content->fetchAll(\PDO::FETCH_COLUMN);
            $t1 = microtime(true) - $t;
            echo "hhz_photos_1 count:" . count($rs) . ", time:$t1", PHP_EOL;
            self::consumeContent($rs, $brand_id);
            $m = self::convert(memory_get_usage() - $mem);
            $t1 = microtime(true) - $t;
            echo "hhz_photos_1 complete memory:{$m}, time:$t1", PHP_EOL;
        }

        if ($op & 4) {
            $content = Photos::query("SELECT `id` FROM `hhz_photos_2` WHERE `status` IN (:s1,:s2)", [
                's1' => \Doraemon\model\Photos::STATUS_UNTREATED,
                's2' => \Doraemon\model\Photos::STATUS_SUCCESS]);
            $rs = $content->fetchAll(\PDO::FETCH_COLUMN);
            $t1 = microtime(true) - $t;
            echo "hhz_photos_2 count:" . count($rs) . ", time:$t1", PHP_EOL;
            self::consumeContent($rs, $brand_id);
            $m = self::convert(memory_get_usage() - $mem);
            $t1 = microtime(true) - $t;
            echo "hhz_photos_2 complete memory:$m, time:$t1", PHP_EOL;
        }

        if ($op & 8) {
            $content = Photos::query("SELECT `id` FROM `hhz_photos_3` WHERE `status` IN (:s1,:s2)", [
                's1' => \Doraemon\model\Photos::STATUS_UNTREATED,
                's2' => \Doraemon\model\Photos::STATUS_SUCCESS]);
            $rs = $content->fetchAll(\PDO::FETCH_COLUMN);
            $t1 = microtime(true) - $t;
            echo "hhz_photos_3 count:" . count($rs) . ", time:$t1", PHP_EOL;
            self::consumeContent($rs, $brand_id);
            $m = self::convert(memory_get_usage() - $mem);
            $t1 = microtime(true) - $t;
            echo "hhz_photos_3 complete memory:$m, time:$t1", PHP_EOL;
        }

        if ($op & 16) {
            $rs = Blank::select('bid', ['status' => [\Doraemon\model\Blank::STATUS_WAIT_CHECK, \Doraemon\model\Blank::STATUS_SUCCESS]]);
            $t1 = microtime(true) - $t;
            echo "hhz_blank count:" . count($rs) . ", time:$t1", PHP_EOL;
            self::consumeContent($rs, $brand_id);
            $m = self::convert(memory_get_usage() - $mem);
            $t1 = microtime(true) - $t;
            echo "hhz_blank complete memory:$m, time:$t1", PHP_EOL;
        }
    }

    public static function contentMatch($content, $match)
    {
        $content = strtolower($content);
        $match = strtolower($match);
        //如果匹配词仅仅是英文,需要完全匹配
        if (preg_match('/^[a-z]*$/', $match)) {
            $pattern = "/\b($match)\b/";
            return preg_match($pattern, $content) > 0;
        }

        return strstr($content, $match);
    }

    public static $matchBrandWordsMap = [];
    public static $brandUidMap = [];
    public static $brandName = [];

    public static function test($op_brand_id = 0)
    {
        list(
            'matchBrandWordsMap' => $matchBrandWordsMap,
            'brandUidMap' => $brandUidMap,
            'brandName' => $brandName) = self::getBrandKeyWords($op_brand_id);

        var_dump($brandName);
    }
    public static function readWordCache($op_brand_id = 0): array
    {
        if (empty(self::$brandName)) {
            list(
                'matchBrandWordsMap' => self::$matchBrandWordsMap,
                'brandUidMap' => self::$brandUidMap,
                'brandName' => self::$brandName) = self::getAllBrandKeyWords();
        }
        if ($op_brand_id) {
            $op_brand_id = is_scalar($op_brand_id) ? [$op_brand_id] : $op_brand_id;
            foreach ($op_brand_id as $id) {
                $matchBrandWordsMap = [$id => self::$matchBrandWordsMap[$id] ?? []];
                $brandUidMap = [$id => self::$brandUidMap[$id] ?? []];
                $brandName = [$id => self::$brandName[$id] ?? []];
            }
        } else {
            $matchBrandWordsMap = self::$matchBrandWordsMap;
            $brandUidMap = self::$brandUidMap;
            $brandName = self::$brandName;
        }
        return compact('matchBrandWordsMap', 'brandUidMap', 'brandName');
    }

    /**
     * 自动收录内容
     * @param        $obj_id
     * @param string $op_brand_id
     * @param bool $cover
     * @return bool
     */
    public static function autoClaim($obj_id, $op_brand_id = '', $cover = true)
    {
        if (is_scalar($op_brand_id)) $op_brand_id = explode(',', $op_brand_id);
        $op_brand_id = array_filter($op_brand_id);
        $op_brand_id = array_values((array)$op_brand_id);

        $obj_type = IdSender::getType($obj_id);
        if ($obj_type == IdSender::TYPE_ANSWER) $obj_type = IdSender::TYPE_PHOTO;

        //查询内容管理的wiki和内容
        $obj_info = AdmContent::get($obj_type, $obj_id);

        if (empty($obj_info) || ($obj_type == BlockType::TYPE_ARTICLE)) {
            Log::position_info("内容为空", compact('obj_id', 'obj_info'));
            return false;
        }
        $obj_info = empty($obj_info) ? [] : $obj_info[$obj_id];
        $uid = $obj_info['uid'] ?? 0;
        $wikiType = [
            0 => \Biz\model\wiki\ObjRelateWiki::OBJ_TYPE_NOTE,
            1 => \Biz\model\wiki\ObjRelateWiki::OBJ_TYPE_ARTICLE,
            5 => \Biz\model\wiki\ObjRelateWiki::OBJ_TYPE_BLANK,
        ];

        //查询内容关联的wiki
        $wiki = ObjRelateWiki::getRelateListByObjIds($wikiType[$obj_type], [$obj_id]);
        $wiki = empty($wiki) ? [] : $wiki[$obj_id];
        $wiki_ids = empty($wiki) ? [] : array_column($wiki, 'wiki_id');
        $wiki_info = empty($wiki_ids) ? [] : \Biz\model\wiki\Wiki::select([
            'id',
            'title',
            'basic_id',
            'brand_id',
            'channel_type',
            'channel_spu_id'
        ], ['id' => $wiki_ids]);
        $wiki_info = empty($wiki_ids) ? [] : array_column($wiki_info, null, 'id');

        //查询内容关联的点图标签
        $tags = [];
        switch ($obj_type) {
            case 0:
                $stickers = \Doraemon\model\PicStickers::getStickersByNoteId($obj_id);
                $stickersMap = empty($stickers) ? [] : array_column($stickers, 'img_tags');
                foreach ($stickersMap as $v) {
                    $tags = array_merge($tags, ObjRelateWiki::admFormatImgTags($v, false));
                }
                break;
            case 1:
                $article_space_list = \Doraemon\model\ArticlePhoto::getArticleSpaceInfoById($obj_id);
                if ($article_space_list && is_array($article_space_list)) {
                    $note_id = [];
                    foreach ($article_space_list as $key => $space_info) {
                        //获取整屋关联的图片
                        $show_pics_arr = json_decode($space_info['show_pics'], true);
                        foreach ($show_pics_arr as $pic) {
                            $note_id[] = $pic['photo_id'];
                        }
                    }
                    $stickers = empty($note_id) ? [] : \Doraemon\model\PicStickers::getStickersByNoteId($note_id);
                    $stickersMap = empty($stickers) ? [] : array_column($stickers, 'img_tags');
                    foreach ($stickersMap as $v) {
                        $tags = array_merge($tags, ObjRelateWiki::admFormatImgTags($v, false));
                    }
                }
                break;
        }


        list(
            'matchBrandWordsMap' => $matchBrandWordsMap,
            'brandUidMap' => $brandUidMap,
            'brandName' => $brandName) = self::readWordCache($op_brand_id);

        //品牌商忽略的wiki
        $ignore = self::getAllIgnore($op_brand_id);


        $brand_ids = [];
        if ($brandName) {
            foreach ($brandName as $id => $v) {
                if ($uid > 0 && $uid == $v['uid']) $brand_ids[$id] = $id;
            }
        }

        //关联商品中与品牌商商品一致的直接收录
        $redirectWiki = [];
        $matchWiki = [];
        foreach ($wiki_info as $id => $wiki) {
            $brand_id = $wiki['brand_id'] ?? 0;
            $tempIgnore = $ignore[$brand_id] ?? [];
            if ($brand_id <= 0 || in_array($id, $tempIgnore)) continue;
            if (!empty($op_brand_id) && !in_array($brand_id, $op_brand_id)) continue;
            $check = \Biz\model\wiki\WikiBasic::count(['id' => $wiki['basic_id'], 'basic_state' => \Biz\model\wiki\WikiBasic::ADM_ALLOW_STATE]);
            if ($check > 0) {
                $redirectWiki[$brand_id][] = $id;
                $matchWiki[$brand_id][] = $id;
                $brand_ids[$brand_id] = $brand_id;
            }
        }

        $matchContent = [];

        if (empty($matchBrandWordsMap)) return false;

        $wikiTitleHit = [];
        $wordsMap = [];
        $search_type = [];
        //遍历匹配内容
        foreach ($matchBrandWordsMap as $brand_id => $words) {
            $hit = false;

            //点图标签命中一级品牌词
            foreach ($tags as $tag) {
                foreach ($words as $word) {
                    if (mb_stripos($tag, $word) !== false) {
                        $hit = true;
                        $brand_ids[$brand_id] = $brand_id;
                        $wordsMap[$brand_id]['tag'][$word] = $word;
                    }
                }
            }

            //商品内容命中一级品牌词
            foreach ($words as $word) {
                $titleMatch = self::contentMatch($obj_info['title'] ?? '', $word);
                $contentMatch = self::contentMatch($obj_info['content'] ?? '', $word);

                if ($titleMatch || $contentMatch) {
                    $hit = true;
                    $brand_ids[$brand_id] = $brand_id;
                    $wordsMap[$brand_id]['content'][$word] = $word;
                }
            }

            //商品名称命中一级品牌词

            
            $brand_name = $brandName[$brand_id]['brand_name'] ?? '';
            $brand_alias = $brandName[$brand_id]['brand_alias'] ? json_decode($brandName[$brand_id]['brand_alias'],true) : [];
            $search_keywords = isset($brandName[$brand_id]['search_keywords']) ? explode(',', $brandName[$brand_id]['search_keywords']) : [];

            $new_map = [];
            foreach ($wordsMap as $map) {
                $map['tag'] = $map['tag'] ?? [];
                $map['content'] = $map['content'] ?? [];
                $new = array_merge($map['tag'], $map['content']);
                foreach ($new as $val) {
                    $new_map[] = $val;
                }
            }
            
            foreach ($new_map as $item){
                if ($brand_name){
                    if (trim($brand_name) && mb_stripos($item, $brand_name) !== false) {
                        $wordsMap[$brand_id]['brand_name'][$brand_name] = $brand_name;
                        $search_type[$brand_id][] = Content::SEARCH_TYPE_BRAND_NAME;
                    }
                }
                if ($brand_alias){
                    foreach ($brand_alias as $alias) {
                        if (trim($alias) && mb_stripos($item, $alias) !== false) {
                            $wordsMap[$brand_id]['brand_alias'][$alias] = $alias;
                            $search_type[$brand_id][] = Content::SEARCH_TYPE_BRAND_ALIAS;
                        }
                    }
                }
                if ($search_keywords){
                    foreach ($search_keywords as $keywords) {
                        if (trim($keywords) && mb_stripos($item, $keywords) !== false) {
                            $wordsMap[$brand_id]['search_keywords'][$keywords] = $keywords;
                            $search_type[$brand_id][] = Content::SEARCH_TYPE_BRAND_KEYWORDS;
                        }
                    }
                }
                $search_type[$brand_id] = isset($search_type[$brand_id])? array_unique($search_type[$brand_id]): [];
            }
    
            if ($hit) $matchContent[] = $brand_id;
        }

        \Doraemon\tools\Log::position_info("autoClaim hit $obj_id", [
            'op_brand_id' => $op_brand_id,
            'content' => $obj_info['content'] ?? '',
            'title' => $obj_info['title'] ?? '',
            'matchBrandWordsMap' => array_keys($matchBrandWordsMap),
            'tags' => $tags,
            'ignore' => $ignore,
            'wiki_info' => array_keys($wiki_info),
            'brand_ids' => $brand_ids,
            'matchWiki' => $matchWiki,
            'redirectWiki' => $redirectWiki,
            'matchContent' => $matchContent,
            'wikiTitleHit' => $wikiTitleHit,
            'wordsMap' => $wordsMap,
        ]);

        if (self::$debug) return false;

        //查询审核通过的数据
        $except_id = $cover ? [] : self::exceptBrandContentId($obj_type, $obj_id);

        //清除内容关联,wiki关联
        self::autoClaimClearRelate($obj_type, $obj_id, $brand_ids, $op_brand_id, $except_id);

        //品牌命中列表
        foreach ($brand_ids as $brand_id) {
            try {
                $match_status = 0;
                $tempMatchWiki = $matchWiki[$brand_id] ?? [];
                $tempRedirectWiki = $redirectWiki[$brand_id] ?? [];
                $brand_uid = $brandUidMap[$brand_id] ?? 0;
                $brand_uid = $brand_uid == ($obj_info['uid'] ?? 0) ? $brand_uid : 0;
                $words = $wordsMap[$brand_id] ?? [];
                $type = isset($search_type[$brand_id]) ?implode(",",$search_type[$brand_id]) : '';

                if ($brand_uid > 0) $match_status |= mBrandContent::MATCH_SELF;
                if (!empty($words['tag'])) $match_status |= mBrandContent::MATCH_TAG_HIT;
                if (!empty($words['content'])) $match_status |= mBrandContent::MATCH_CONTENT_HIT;

                //内容关联的wiki
                $wiki_num = 0;
                $wiki_status = 0;
                foreach ($tempMatchWiki as $wiki_id) {
                    $direct = in_array($wiki_id, $tempRedirectWiki);
                    if ($direct) {
                        $wiki_num++;
                        $match_status |= mBrandContent::MATCH_BRAND_WIKI;
                    } else {
                        $wiki_status++;
                        $match_status |= mBrandContent::MATCH_WIKI_TITLE;
                    }
                }

                //保存认领内容
                $cid = self::autoClaimSaveContent(
                    $brand_id,
                    $brand_uid,
                    $obj_type,
                    $obj_id,
                    $matchContent,
                    $tempRedirectWiki,
                    $except_id,
                    $wiki_num,
                    $wiki_status,
                    $match_status,
                    $words,
                    $type
                );

                if ($cid === false) continue;

                //更新wiki关联的状态(仅处理删除的商品)
                $data = [
                    'relation' => \Biz\model\brand\ContentWiki::RELATION_NONE,
                    'audit_status' => mBrandContent::AUDIT_STATUS_NONE,
                ];
                $where = [
                    'brand_id' => $brand_id,
                    'obj_type' => $obj_type,
                    'obj_id' => $obj_id,
                    'relation[!]' => \Biz\model\brand\ContentWiki::RELATION_IGNORE,
                ];
                if (!empty($tempMatchWiki)) $where['wiki_id[!]'] = $tempMatchWiki;
                \Biz\model\brand\ContentWiki::update($data, $where);

                //内容关联的wiki
                foreach ($tempMatchWiki as $wiki_id) {
                    $direct = in_array($wiki_id, $tempRedirectWiki);
                    self::autoClaimSaveWiki(
                        $brand_id,
                        $brand_uid,
                        $obj_type,
                        $obj_id,
                        $cid,
                        $wiki_id,
                        $direct,
                        '自动修改关联wiki',
                        false
                    );
                }
            } catch (\Exception $e) {
                \Doraemon\tools\Log::position_info("autoClaim error", [
                    $e->getMessage(),
                    $brand_id,
                    $brand_uid,
                    $obj_type,
                    $obj_id,
                    $cid ?? 0,
                    $tempMatchWiki,
                    $tempRedirectWiki,
                ]);
            }
        }

    }

    /**
     * 保存认领内容
     * @param $brand_id
     * @param $brand_uid
     * @param $obj_type
     * @param $obj_id
     * @param $matchContent
     * @param $tempRedirectWiki
     * @param $except_id
     * @param $wiki_num
     * @param $wiki_status
     * @param $match_status
     * @param $words
     * @return int|mixed|string
     * @throws \Exception
     */
    protected static function autoClaimSaveContent(
        $brand_id,
        $brand_uid,
        $obj_type,
        $obj_id,
        $matchContent,
        $tempRedirectWiki,
        $except_id,
        $wiki_num,
        $wiki_status,
        $match_status,
        $words,
        $type
    )
    {
        $tempMatchContent = in_array($brand_id, $matchContent);

        //如果商品id直接匹配,内容直接关联 || 品牌商发的内容直接关联
        if ($tempRedirectWiki || ($brand_uid > 0)) {
            $claim_content_status = mBrandContent::CLAIM_CONTENT_DONE;
            $claim_time = date("Y-m-d H:i:s");
            $audit_status = mBrandContent::AUDIT_STATUS_AUTO;
        } else {
            $claim_content_status = mBrandContent::CLAIM_CONTENT_MATCH;
            $audit_status = mBrandContent::AUDIT_STATUS_NONE;
        }

        $words = array_map(function ($v) {
            return array_values($v);
        }, $words);

        $words = json_encode($words, JSON_UNESCAPED_UNICODE);
        $data = [
            'words' => $words,
            'wiki_num' => $wiki_num,
            'wiki_status' => $wiki_status,
            'claim_type' => mBrandContent::CLAIM_TYPE_NONE,
            'audit_status' => $audit_status,
            'last_audit_status' => mBrandContent::AUDIT_STATUS_NONE,
            'claim_content_status' => $claim_content_status,
            'content_status' => $tempMatchContent ? mBrandContent::CLAIM_WAIT_MATCH : mBrandContent::CLAIM_NONE_MATCH,
            'brand_uid' => $brand_uid,
            'match_status' => $match_status,
            'search_type' => $type
        ];

        if (isset($claim_time)) $data['claim_time'] = $claim_time;
        if (isset($claim_time)) $data['first_claim_time'] = $claim_time;

        //查询记录是否存在
        $existsData = [
            'brand_id' => $brand_id,
            'obj_type' => $obj_type,
            'obj_id' => $obj_id,
        ];
        $exists = mBrandContent::get('*', $existsData);
        $id = $exists['id'] ?? 0;
        //已经存在的
        if (in_array($id, $except_id) && ($audit_status != mBrandContent::AUDIT_STATUS_AUTO)) {
            //查询商家手动追加的商品
            $count = $id > 0 ? \Biz\model\brand\ContentWiki::count([
                'cid' => $id,
                'relation' => [
                    \Biz\model\brand\ContentWiki::RELATION_DONE,
                ],
                'operation_mode' => \Biz\model\brand\ContentWiki::OPERATION_MODE_EXTEND,
            ]) : 0;
            $wiki_num += $count;
            if (($wiki_num != $exists['wiki_num']) || ($wiki_status != $exists['wiki_status'])) {
                mBrandContent::update(['wiki_num' => $wiki_num, 'wiki_status' => $wiki_status, 'words' => $words, 'search_type'=>$type], ['id' => $id]);
                return $id;
            } else {
                mBrandContent::update(['brand_uid' => $brand_uid, 'match_status' => $match_status, 'words' => $words,'search_type'=>$type], ['id' => $id]);
                return false;
            }
        }

        if (isset($exists['first_claim_time']) && $exists['first_claim_time'] != '0000-00-00 00:00:00') unset($data['first_claim_time']);

        if ($id) {
            //如果已经忽略和取消收录这条内容,不再修改匹配状态和认领状态
            if (in_array($exists['claim_content_status'], [mBrandContent::CLAIM_CONTENT_IGNORE, mBrandContent::CLAIM_CONTENT_CANCEL])) {
                unset($data['claim_content_status'], $data['audit_status'], $data['last_audit_status'], $data['claim_type']);
            }
            $obj_is_delete = self::getContentStatus($obj_id);
            if ($obj_is_delete){
                $data['claim_content_status'] = mBrandContent::CLAIM_CONTENT_IGNORE;
            }
            mBrandContent::update($data, ['id' => $id]);

            //添加操作日志
            self::addTrace('修改收录内容', $brand_id, $obj_id, mBrandContent::log());

        } else {
            $data['addtime'] = date("Y-m-d H:i:s");
            $rs = mBrandContent::insert($data + $existsData)->rowCount();
            if (!$rs) throw new \Exception('添加自动收录记录失败');

            $id = mBrandContent::id();
            $actionUid = $existsData['brand_id'] ? mBrand::getBrandUidById($existsData['brand_id']) : 0;
            if ($actionUid) {
                ActionLog::log($actionUid, [], ActionLog::BRAND_AUTO_CLAIM_WIKI_CONTENT);
                Sensors::track($actionUid, [], ActionLog::BRAND_AUTO_CLAIM_WIKI_CONTENT);
            }

            //添加操作日志
            self::addTrace('收录内容', $brand_id, $obj_id, mBrandContent::log());
        }
        return $id;
    }

    /**
     * @param        $brand_id
     * @param        $brand_uid
     * @param        $obj_type
     * @param        $obj_id
     * @param        $cid
     * @param        $wiki_id
     * @param        $direct
     * @param string $title
     * @param bool $flag
     * @throws \Exception
     */
    public static function autoClaimSaveWiki(
        $brand_id,
        $brand_uid,
        $obj_type,
        $obj_id,
        $cid,
        $wiki_id,
        $direct,
        $title = '自动修改关联wiki',
        $flag = true //true 手动认领
    )
    {
        //如果商品id直接匹配或者待确认

        $relation = $direct ? \Biz\model\brand\ContentWiki::RELATION_DONE : \Biz\model\brand\ContentWiki::RELATION_MATCH;
        $data = [
            'brand_uid' => $brand_uid,
            'brand_id' => $brand_id,
            'obj_type' => $obj_type,
            'obj_id' => $obj_id,
            'wiki_id' => $wiki_id,
            'claim_wiki_id' => $flag && $direct ? $wiki_id : 0,
            'cid' => $cid,
            'relation' => $relation,
            'operation_mode' => $flag ? \Biz\model\brand\ContentWiki::OPERATION_MODE_EXTEND : \Biz\model\brand\ContentWiki::OPERATION_MODE_AUTO,
            'audit_status' => !$flag && $direct ? mBrandContent::AUDIT_STATUS_AUTO : mBrandContent::AUDIT_STATUS_NONE
        ];

        //查询记录是否存在
        $existsData = [
            'cid' => $cid,
            'wiki_id' => $wiki_id,
        ];
        $exists = \Biz\model\brand\ContentWiki::get('*', $existsData);

        $id = $exists['id'] ?? 0;

        if ($id) {
            //如果已经忽略这条内容,不再修改匹配状态和认领状态
            if (in_array($exists['relation'], [\Biz\model\brand\ContentWiki::RELATION_IGNORE])) {
                unset($data['relation']);
            }
            $data['operation_mode'] = $exists['operation_mode'] | $data['operation_mode'];

            \Biz\model\brand\ContentWiki::update($data, ['id' => $id]);

            //添加操作日志
            self::addDebugTrace($brand_id, '', compact('title', 'data'));
        } else {
            $data['addtime'] = date("Y-m-d H:i:s");
            $rs = \Biz\model\brand\ContentWiki::insert($data)->rowCount();
            if (!$rs) throw new \Exception('添加内容关联的wiki记录失败');

            //添加操作日志
            self::addDebugTrace($brand_id, '', compact('title', 'data'));
        }

    }

    public static function exceptBrandContentId($obj_type, $obj_id)
    {
        //没有重置过的数据都排除
        $where = [
            'obj_type' => $obj_type,
            'obj_id' => $obj_id,
            'claim_content_status[!]' => 0,
            'claim_time[!]' => '0000-00-00 00:00:00',
        ];
        $ids = mBrandContent::select('id', $where);
        return empty($ids) ? [] : $ids;
    }

    /**
     * 清除内容关联,wiki关联
     * @param       $obj_type
     * @param       $obj_id
     * @param array $brand_ids
     * @param array $op_brand_id
     * @param array $except_id
     */
    public static function autoClaimClearRelate($obj_type, $obj_id, $brand_ids = [], $op_brand_id = [], $except_id = [])
    {
        //更新内容关联的状态
        $data = [
            'claim_content_status' => mBrandContent::CLAIM_CONTENT_NONE,
            'content_status' => mBrandContent::CLAIM_CONTENT_NONE,
            'wiki_status' => 0,
            'audit_status' => mBrandContent::AUDIT_STATUS_NONE,
        ];
        $where = [
            'obj_type' => $obj_type,
            'obj_id' => $obj_id,
            'claim_content_status[!]' => [mBrandContent::CLAIM_CONTENT_IGNORE, mBrandContent::CLAIM_CONTENT_CANCEL],
        ];
        if ($op_brand_id) {
            $where['brand_id'] = $op_brand_id;
        }
        if ($brand_ids) $where['brand_id[!]'] = $brand_ids;
        if ($except_id) $where['id[!]'] = $except_id;

        $ids = mBrandContent::select('id', $where);
        if ($ids) {
            mBrandContent::update($data, ['id' => $ids]);

            //更新wiki关联的状态
            $data = [
                'relation' => \Biz\model\brand\ContentWiki::RELATION_NONE,
                'audit_status' => mBrandContent::AUDIT_STATUS_NONE,
            ];
            $where = [
                'obj_type' => $obj_type,
                'obj_id' => $obj_id,
                'relation[!]' => \Biz\model\brand\ContentWiki::RELATION_IGNORE,
            ];
            if ($op_brand_id) {
                $where['brand_id'] = $op_brand_id;
            }
            if ($brand_ids) $where['brand_id[!]'] = $brand_ids;
            if ($except_id) $where['cid[!]'] = $except_id;

            \Biz\model\brand\ContentWiki::update($data, $where);
        }

        //debug 日志
        self::addDebugTrace(0, $obj_id, [
            '清除内容关联',
            'data' => $data,
            'where' => $where,
            'ids' => $ids,
        ]);

    }


    public static function getContentStatus($obj_id): bool
    {
        $obj_type = IdSender::getType($obj_id);
        if ($obj_type == BlockType::TYPE_PHOTO || $obj_type == BlockType::TYPE_ANSWER) {
            $status = \Doraemon\model\Photos::get('status', ['id' => $obj_id]);
            if (isset($status) && in_array($status, [Photos::STATUS_DELETE, Photos::STATUS_FORCE_OUT],false)) {
                return true;
            }
        } else if ($obj_type == BlockType::TYPE_BLANK) {
            $status = \Doraemon\model\Blank::get('status', ['bid' => $obj_id]);
            if (isset($status) && in_array($status,[Blank::STATUS_DELETE,Blank::STATUS_FORCE_OUT],false)) {
                return true;
            }
        }
        return false;
    }
}
